package p2pscrabble;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class SaveGameValidator {
	private Connection c;
	private String filename;

	private GameState my;
	private GameState opp;

	XStream xs = new XStream(new DomDriver());

	public SaveGameValidator(Connection c, String filename) {
		this.c = c;
		this.filename = filename;
	}

	public boolean checkSaveFileExists() {
		File f = new File(filename);

		if (!f.exists())
			return false;

		return true;
	}

	public boolean validateSaveGame() {
		my = loadStateFromFile(filename);
		String oppxml = null;

		// send n receive game state
		c.send_game_state(my.toXML());
		oppxml = c.receive_game_state();
		opp = (GameState) xs.fromXML(oppxml);
		// opp.print();

		System.out.println(checkSameTurn());

		if (checkSameTurn() && compare2Save())
			return true;
		else if (checkSameTurn() && !compare2Save()) {
			return false;
		} else if (!checkSameTurn() && compare2Save()) {
			if (my.getTurn() == (opp.getTurn() + 1)) {
				filename = filename + "old";
				System.out.println(filename);
				if (!checkSaveFileExists()) {
					c.send_data("NO SAVE GAME");
					return false;
				}
				c.send_data("TRY");
				my = loadStateFromFile(filename);
				c.send_game_state(my.toXML());
			} else if (my.getTurn() == (opp.getTurn() - 1)) {
				if (c.receive_data().startsWith("NO"))
					return false;
				opp = (GameState) xs.fromXML(c.receive_game_state());
			}
			return compare2Save();
		}

		return false;
	}

	public boolean checkSameTurn() {
		return my.getTurn() == opp.getTurn();
	}

	public boolean compare2Save() {
		// conditions that is possible to happen
		boolean cond0 = checkSameTurn();

		boolean cond1 = my.getBagCounter() == opp.getBagCounter();
		boolean cond2 = new String(my.getBagLetter()).equals(new String(opp
				.getBagLetter()));
		boolean cond3 = new String(my.getPlayer1Letter()).equals(new String(opp
				.getPlayer1Letter()));
		boolean cond4 = new String(my.getPlayer2Letter()).equals(new String(opp
				.getPlayer2Letter()));
		boolean cond5 = my.getPlayer1Score() == opp.getPlayer1Score();
		boolean cond6 = my.getPlayer2Score() == opp.getPlayer2Score();
		boolean cond7 = checkBoardTable();

		System.out.println("" + cond0 + cond1 + cond2 + cond3);
		System.out.println("" + cond4 + cond5 + cond6 + cond7);

		// state number is the same
		if (cond0) {
			// all OK
			if (cond1 && cond2 && cond3 && cond4 && cond5 && cond6 && cond7)
				return true;
		}
		// differ by 1 state number
		else {
			// submitting
			if ((!cond1 && cond2 && !cond5 && cond6 && !cond7)
					|| (!cond1 && cond2 && cond5 && !cond6 && !cond7))
				return true;
			// swapping
			if ((cond1 && !cond2 && cond5 && cond6 && cond7)
					|| (cond1 && !cond2 && cond5 && cond6 && cond7))
				return true;
		}
		return false;
	}

	public GameState loadStateFromFile(String filename) {
		try {
			FileReader fstream = new FileReader(filename);
			BufferedReader in = new BufferedReader(fstream);

			GameState temp = (GameState) xs.fromXML(in);

			in.close();

			return temp;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public GameState fromString(String s) {
		return (GameState) xs.fromXML(s);
	}

	public GameState getMy() {
		return my;
	}

	public boolean checkBoardTable() {
		for (int i = 0; i < 15; i++)
			for (int j = 0; j < 15; j++)
				if (my.getBoardLetter()[i][j] != opp.getBoardLetter()[i][j])
					return false;
		return true;
	}
}
